//
// Created by wyh on 2025-07-13 20:59.
//

#ifndef FRAMEWORK_CPP_XML_H
#define FRAMEWORK_CPP_XML_H

#include <string>
#include <map>
#include <vector>

#include "utility/value.h"

namespace wyh {
    namespace xml {
        class Xml
        {
        public:
            Xml() = default;

            Xml(const char *name);

            Xml(const std::string &name);

            Xml(const Xml &other);

            Xml(Xml &&other);

            ~Xml();

            std::string name() const;

            void name(const std::string &name);

            std::string text() const;

            void text(const std::string &text);

            utility::Value &attr(const std::string &key);

            void attr(const std::string &key, const utility::Value &value);

            void append(const Xml &child);
            void append(Xml &&child);

            void remove(int index);

            void remove(const char *name);

            void remove(const std::string &name);

            Xml &operator[](int index);
            Xml &operator[](const char *name);
            Xml &operator[](const std::string &name);

            Xml &operator=(const Xml &other);
            Xml &operator=(Xml &&other) noexcept;

            int size() const;
            bool empty() const;
            void clear();

            typedef std::vector<Xml>::iterator iterator;

            iterator begin()
            {
                return m_childs.begin();
            }

            iterator end()
            {
                return m_childs.end();
            }

            iterator erase(iterator it)
            {
                it->clear();
                return m_childs.erase(it);
            }


            std::string str() const;
            friend std::ostream &operator<<(std::ostream &os, const Xml &xml)
            {
                os<<xml.str();
                return os;
            }

            bool load(const std::string &filename);
            bool load(const char *buf,int len);
            bool save(const std::string &filename);

        private:
            void copy(const Xml &other);

            void swap(Xml &other);

        private:
            std::string m_name;
            std::string m_text;
            std::map<std::string, utility::Value> m_attrs;
            std::vector<Xml> m_childs;
        };
    } // namespace Xml
} // namespace wyh

#endif //FRAMEWORK_CPP_XML_H
